import type { Translate } from '@renderer/service'
import { post, get } from '@renderer/utils'

enum Locale {
    'auto' = 'auto-detect',
    'zh-CN' = 'zh-Hans',
    'en-US' = 'en',
    'zh-TW' = 'zh-Hant'
}


type BingTranslateResponse = [{translations: [{text: string}]}]


export default class BingTranslate implements Translate{
    public readonly name = "必应翻译";
    public readonly id = crypto.randomUUID();
    public readonly delay = 0;
    private token = ''
    private key = ''
    private ig = ''
    constructor(){
        this.getAuthorization()
    }

    translate(keywords: string, to: string, from: string = Locale.auto){
        const params = this.createParams(keywords, to, from)
        return new Promise<TranslateResponse>((resolve,reject) => {
            post<BingTranslateResponse>(`https://www.bing.com/ttranslatev3?IG=${this.ig}&IID=translator`, params, {
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
            }).then(res => {
                resolve({ status: 'success', from, to, keywords, data: res[0].translations[0].text})
            }).catch(e => {
                if(e instanceof PromiseRejectionEvent) reject(new Error(e.reason))
				if(e instanceof Error) reject(new Error(e.message))
            })
        })
    }


    createParams(text: string, to: string, from: string){
        return { fromLang: Locale[from], to:Locale[to], text, token: this.token, key: this.key }
    }

    private getAuthorization(){
        get<string>('https://www.bing.com/translator', {}, {
            responseType: 'text'
        }).then(res => {
            const igRegex = /IG:"(\w+)"/
            const matchIG = res.match(igRegex)
            if (matchIG) this.ig = matchIG[1];
            const tokenRegex = /params_AbusePreventionHelper\s*=\s*(\[.*?\]);/
            const matchToken = res.match(tokenRegex);
            if(!matchToken) return
            const data = matchToken[1];
            const [key, token] = data.replaceAll("[","").replaceAll("]","").replaceAll('"', '').split(",").map(item => item.trim())
            this.key = key
            this.token = token
        })
    }
}